package cn.tedu.charging.device.dao.repository.impl;

import cn.tedu.charging.device.dao.repository.AbstractStationCacheRepository;
import cn.tedu.charging.device.dao.repository.StationCacheRepository;
import cn.tedu.charging.device.pojo.po.StationCanalPO;
import cn.tedu.charging.device.pojo.po.StationPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 位置信息 GEO
 * 基本信息 Hash
 *
 * Map<bigKey,Map<hashKey,value>>
 *
 * bigKey ?
 * 站点id stationId
 * hashKey ?
 * 站属性名 stationName
 * value  ?
 * 站属性值 充的快充电站
 *
 * Map<bigKey,Map<hashKey,value>> map = new HashMap();
 *
 * Map<hashKey,value> small = new HashMap();
 *
 *              站属性名      站属性值
 * small.put("stationName","充的快充电站");
 * small.put("status","营业中");
 * small.put("gunNum",100);
 *
 * map.put("stationId",map);
 *
 *
 * Map<bigKey,Map<hashKey,value>> map = new HashMap();
 *
 * Map<hashKey,value> small = new HashMap();
 *              站id        站完整信息
 * small.put("stationId5","stationPO");
 * small.put("stationId4","stationPO");
 * small.put("stationId8","stationPO");
 *
 * map.put("stationHash",map);
 *
 * PO属性拆开的方式   一个站 一个Hash  独享
 * Redis的 Hash
 * 可以 通过大key 和 HashKey 直接 <获取> 到对应 value                    容易复用
 * 可以 通过大key 和 HashKey 直接 <修改> 到对应 value                    容易修改
 * 如果 站的数据量过大 redis 可以采用 分片技术 不同的站 在不同的分片          容易扩展
 *
 * PO属性不拆开方式   所有站 一个Hash 共享
 *  数量小
 *  容易理解
 *
 *
 */
@Slf4j
@Repository("GeoAndNoShareHash")
public class StationCacheGeoAndNoShareHashRepositoryImpl
        extends AbstractStationCacheRepository
        implements StationCacheRepository {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    @Override
    public void saveAllStation(List<StationPO> stationPOs) {
        //保存映射关系 位置 和 站点id
        saveLocationByGEOAndMemberIsId(stationPOs);
        //保存基本信息到Hash
        saveStationInfoByNoShareHash(stationPOs);
    }

    /**
     * 保存站点信息
     * 不共享 一个站 一个Hash
     *  bigKey  站点id stationId
     *  hashKey 站属性名 stationName
     *  value   站属性值 充的快充电站
     * @param stationPOs
     */
    private void saveStationInfoByNoShareHash(List<StationPO> stationPOs) {
        HashOperations hashOperations = redisTemplate.opsForHash();
        for (StationPO stationPO : stationPOs) {
            String bigKey = "station_info_hash_no_share_" + stationPO.getId();
            String nameHashKey = "stationName";
            String lngHashKey = "lng";
            String latHashKey = "lat";
            Map<String,Object> smallMap = new HashMap<>();
            smallMap.put(nameHashKey,stationPO.getStationName());
            smallMap.put(lngHashKey,stationPO.getStationLng());
            smallMap.put(latHashKey,stationPO.getStationLat());
            hashOperations.putAll(bigKey,smallMap);
        }
    }

    @Override
    public List<StationPO> search(Double lng, Double lat, Double radius) {
        //调用父类的方法 search
        return super.search(lng, lat, radius);
    }

    @Override
    public void update(StationCanalPO stationCanalPO) {
        //Redis的命令的特点 不存在 保存 ，存在更新
    }

    @Override
    public void insert(StationCanalPO stationCanalPO) {
        //Redis的命令的特点 不存在 保存 ，存在更新
    }

    @Override
    public void delete(StationCanalPO stationCanalPO) {
        redisTemplate.delete("station_geo_" + stationCanalPO.getId());
    }

    @Override
    public StationPO getStationInfoById(String stationId){
        String bigKey = "station_info_hash_no_share_" + stationId;

        HashOperations hashOperations = redisTemplate.opsForHash();

        //List<String> hashKeylist = Arrays.asList("stationName", "stationId");
        //通过 大key 和 HashKey 直接 <获取> 到对应 value
        //Object o = hashOperations.get(bigKey, "stationName");
        //通过 大key 和 HashKey列表 直接 <获取> 到对应 value列表
        //List<Object> hashValues = hashOperations.multiGet(bigKey, hashKeylist);
        //通过 大key 小map
        String nameHashKey = "stationName";
        String lngHashKey = "lng";
        String latHashKey = "lat";
        Map<String,Object> smallMap = hashOperations.entries(bigKey);
        Object stationName = smallMap.get(nameHashKey);
        Object lng = smallMap.get(lngHashKey);
        Object lat = smallMap.get(latHashKey);
        StationPO stationPO = new StationPO();
        stationPO.setStationName(String.valueOf(stationName));
        BigDecimal bigDecimalLng = new BigDecimal(String.valueOf(lng));
        BigDecimal bigDecimalLat = new BigDecimal(String.valueOf(lat));
        stationPO.setStationLng(bigDecimalLng);
        stationPO.setStationLat(bigDecimalLat);
        return stationPO;
    }



}
